/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "los_task.h"
#include "los_compiler.h"
#include "ohos_init.h"
#include "ohos_types.h"

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
extern void Hello_World();

/* USER CODE BEGIN PFP */

/**
 * @brief  The application entry point.
 * @retval int
 */
int main(void)
{
	// 重定向中断向量表
	ExceptionInit();
	// 打开时钟
	LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SYSCFG);
	LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR);
	// 初始化中断
	NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
	NVIC_SetPriority(SysTick_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 15, 0));
	// 初始化系统时钟
	SystemClock_Config();
	delay_init();
	// 初始化队列
	QueueInit();
	// 初始化外设
	USART1_UART_Init();
	// 初始化gpio
	GPIO_Init();
	// 初始化f液晶屏
	FSMC_Init();
    delay_ms(500);
	HAL_Delay(500);
    LCD_Init();
	// 初始化flash
    W25QXX_Init();
	// 开启液晶屏
    LCD_DisplayOn();
	LCD_Clear(WHITE);
	printf("flash id is %x\n", W25QXX_ReadID());
    // sd卡初始化
    while(SD_Init())//检测不到SD卡
	{
        printf("sd error\n");
		LCD_ShowString(30,70,112,16,16,"SD Card Error!");
		delay_ms(500);					
		LCD_ShowString(30,70,112,16,16,"Please Check! ");
		delay_ms(500);
	}
    //打印SD卡相关信息
	show_sdcard_info();	
	/**************************  用户代码 ************************** */
	uint32_t ret;
	//初始化内核
	ret = LOS_KernelInit();
	if (ret == LOS_OK) {
		printf("-------liteos_m start------\r\n");
		uart_task();
		// 开始任务调度，程序执行将阻塞在此，由内核接管调度
		LOS_Start();   
	}
}

/**
 * @brief System Clock Configuration
 * @retval None
 */
void SystemClock_Config(void)
{
	LL_FLASH_SetLatency(LL_FLASH_LATENCY_5);
	while (LL_FLASH_GetLatency() != LL_FLASH_LATENCY_5)
	{
	}
	LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE1);
	LL_RCC_HSE_Enable();

	/* Wait till HSE is ready */
	while (LL_RCC_HSE_IsReady() != 1)
	{
	}
	LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, LL_RCC_PLLM_DIV_4, 168, LL_RCC_PLLP_DIV_2);
	LL_RCC_PLL_Enable();

	/* Wait till PLL is ready */
	while (LL_RCC_PLL_IsReady() != 1)
	{
	}
	LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
	LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_4);
	LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_2);
	LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);

	/* Wait till System clock is ready */
	while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL)
	{
	}
	//LL_Init1msTick(168000000);
	LL_SetSystemCoreClock(168000000);
	LL_Tick_Init();
}
/**
 * @brief This function handles Hard fault interrupt.
 */
void HardFault_Handler(void)
{
    /* USER CODE BEGIN HardFault_IRQn 0 */
    /* USER CODE END HardFault_IRQn 0 */
    while (1)
    {
        printf("hard fault\r\n");
        delay_us(1000 * 1000);
    }
}

/**
 * @brief This function handles Memory management fault.
 */
void MemManage_Handler(void)
{
    /* USER CODE BEGIN MemoryManagement_IRQn 0 */
    printf("mem fault\r\n");
    /* USER CODE END MemoryManagement_IRQn 0 */
    while (1)
    {
        printf("mem fault\r\n");
        delay_us(5000 * 1000);
    }
}

/**
 * @brief This function handles Pre-fetch fault, memory access fault.
 */
void BusFault_Handler(void)
{
    /* USER CODE BEGIN BusFault_IRQn 0 */
    /* USER CODE END BusFault_IRQn 0 */
    while (1)
    {
        printf("bus fault\r\n");
        delay_us(1000 * 1000);
    }
}
void UsageFault_Handler(void)
{
    /* USER CODE BEGIN UsageFault_IRQn 0 */
    /* USER CODE END UsageFault_IRQn 0 */
    while (1)
    {
        printf("usage fault handler\r\n");
        delay_us(1000*1000);
    }
}
void ExceptionInit()
{
    /**************参考CORTEX-M3权威手册 ************/
    // 复制HardFault_Handler
    uint32_t *vectors = (uint32_t *)(0x20000000 + 8);
    *vectors = (uint32_t)HardFault_Handler;

    // 重定向 向量表
    SCB->VTOR = 0x20000000 | (0 & (uint32_t)0x1FFFFF80);

    NVIC_SetVector(MemoryManagement_IRQn, MemManage_Handler);
    // 配置MemManage Fault 中断优先级，实际上配置的是SCB->SHP 寄存器
    NVIC_SetPriority(MemoryManagement_IRQn, 0);
    // 使能MemManage Fault 中断或异常, 实际上设置SCB->SHCSR 的bit 16 为 1
    SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;

    NVIC_SetVector(BusFault_IRQn, BusFault_Handler);
    // 配置Bus Fault 中断优先级，实际上配置的是SCB->SHP 寄存器
    NVIC_SetPriority(BusFault_IRQn, 0);
    // 使能Bus Fault 中断或异常, 实际上设置SCB->SHCSR 的bit 17 为 1
    SCB->SHCSR |= SCB_SHCSR_BUSFAULTENA_Msk;

    NVIC_SetVector(UsageFault_IRQn, UsageFault_Handler);
    // 配置Usage fault 中断优先级，实际上配置的是SCB->SHP 寄存器
    NVIC_SetPriority(UsageFault_IRQn, 0);
    // 使能Usage fault 中断或异常, 实际上设置SCB->SHCSR 的bit 18 为 1
    SCB->SHCSR |= SCB_SHCSR_USGFAULTENA_Msk;
}

/**
 * @brief  This function is executed in case of error occurrence.
 * @retval None
 */
void Error_Handler(void)
{
	/* USER CODE BEGIN Error_Handler_Debug */
	/* User can add his own implementation to report the HAL error return state */
	__disable_irq();
	while (1)
	{
	}
	/* USER CODE END Error_Handler_Debug */
}

#ifdef USE_FULL_ASSERT
/**
 * @brief  Reports the name of the source file and the source line number
 *         where the assert_param error has occurred.
 * @param  file: pointer to the source file name
 * @param  line: assert_param error line source number
 * @retval None
 */
void assert_failed(uint8_t *file, uint32_t line)
{
	/* USER CODE BEGIN 6 */
	/* User can add his own implementation to report the file name and line number,
	   ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
	/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
